package im.eg.service;

import cn.hutool.core.util.StrUtil;
import im.eg.spring.anno.Component;
import im.eg.spring.itfs.BeanPostProcessor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 定义BeanPostProcessor实现类，字面上理解额外为bean后置处理器，根据两个方法可知其提供了实例化前和实例化后两个回调
 * <p>
 * 实例化 --> 属性注入 --> Aware回调 --> 初始化前 --> 初始化afterPropertiesSet --> init-method --> 初始化后 --> 销毁回调 --> destroy-method
 * ref: https://blog.csdn.net/riemann_/article/details/118500805
 */
@Component("egBeanPostProcessor")
public class EgBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("初始化前 - " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("初始化后 - " + beanName);

        // aop模拟 - 1 - 判断bean的方法是否需要进行aop
        if (StrUtil.isNotBlank(beanName) && "studentService".equals(beanName)) {
            return Proxy.newProxyInstance(EgBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                    // aop模拟 - 2 - aop模拟 - 2 - 如需进行aop，则将切面逻辑”放入“代理对象的代理逻辑（这里使用jdk代理做演示，实际情况可能会使用cglib代理）
                    long start = System.currentTimeMillis();
                    Object result = method.invoke(bean, args);
                    long end = System.currentTimeMillis();
                    System.out.println(method.getName() + " 执行耗时 " + (end - start) + "ms");
                    return result;
                }
            });
        }

        return bean;
    }
}
